﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using xTeam.Hengle.Alipay;
using ShopB2C.ViewModels;
using xTeam.HengLe.Entity;
using xTeam.HengLe.Entity.Enums;
using System.IO;

namespace xTeam.HengLe.Controller.Website
{
    public class AlipayController:BaseController
    {
        public ActionResult Pay(string orderId)
        {
            int uid = _user.Uid;
            OrderViewModel model = _orderAccess.SaleOrderView(uid, orderId);
            ////////////////////////////////////////////请求参数////////////////////////////////////////////
            
            //必填参数//

            string orderDescription = "";
            if(model.ProductList.Count>0)
            {
                orderDescription = model.ProductList.Count > 1 ? string.Format("Shinnos购物 {0} 等商品", model.ProductList[0].ProductName) : model.ProductList[0].ProductName;
            }
            
            
            string out_trade_no = orderId;  //请与贵网站订单系统中的唯一订单号匹配
            string subject = orderDescription;                    //订单名称，显示在支付宝收银台里的“商品名称”里，显示在支付宝的交易管理的“商品名称”的列表里。
            string body = orderDescription;                          //订单描述、订单详细、订单备注，显示在支付宝收银台里的“商品描述”里
            string price = model.OrderView.Price.ToString("0.00");		        //订单总金额，显示在支付宝收银台里的“商品单价”里

            string logistics_fee = "0.00";                  				//物流费用，即运费。
            string logistics_type = "EXPRESS";				                //物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
            string logistics_payment = "SELLER_PAY";            			//物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

            string quantity = "1";              							//商品数量，建议默认为1，不改变值，把一次交易看成是一次下订单而非购买一件商品。

            //选填参数//

            //买家收货信息（推荐作为必填）
            //该功能作用在于买家已经在商户网站的下单流程中填过一次收货信息，而不需要买家在支付宝的付款流程中再次填写收货信息。
            //若要使用该功能，请至少保证receive_name、receive_address有值
            //收货信息格式请严格按照姓名、地址、邮编、电话、手机的格式填写
            string receive_name = model.Address.ReallyName;			                    //收货人姓名，如：张三
            string receive_address = model.Address.Address;			                //收货人地址，如：XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号
            string receive_zip = model.Address.PostNo;                  			    //收货人邮编，如：123456
            string receive_phone = model.Address.Phone;                		    //收货人电话号码，如：0571-81234567
            string receive_mobile = model.Address.Mobile;               		    //收货人手机号码，如：13312341234

            //网站商品的展示地址，不允许加?id=123这类自定义参数
            string show_url = "http://pic.8valor.com";

            ////////////////////////////////////////////////////////////////////////////////////////////////

            //把请求参数打包成数组
            SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
            sParaTemp.Add("body", body);
            sParaTemp.Add("logistics_fee", logistics_fee);
            sParaTemp.Add("logistics_payment", logistics_payment);
            sParaTemp.Add("logistics_type", logistics_type);
            sParaTemp.Add("out_trade_no", out_trade_no);
            sParaTemp.Add("payment_type", "1");
            sParaTemp.Add("price", price);
            sParaTemp.Add("quantity", quantity);
            sParaTemp.Add("receive_address", receive_address);
            sParaTemp.Add("receive_mobile", receive_mobile);
            sParaTemp.Add("receive_name", receive_name);
            sParaTemp.Add("receive_phone", receive_phone);
            sParaTemp.Add("receive_zip", receive_zip);
            sParaTemp.Add("show_url", show_url);
            sParaTemp.Add("subject", subject);

            //构造担保交易接口表单提交HTML数据，无需修改
            Service ali = new Service();
            string sHtmlText = ali.Create_partner_trade_by_buyer(sParaTemp);
            return Content(sHtmlText);
        }

        public ActionResult AlipayNotify()
        {
            SortedDictionary<string, string> sPara = GetRequestPost();

            if (sPara.Count > 0)//判断是否有带返回参数
            {
                Notify aliNotify = new Notify();
                bool verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);

                if (verifyResult)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码

                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
                    string trade_no = Request.Form["trade_no"];         //支付宝交易号
                    string order_no = Request.Form["out_trade_no"];     //获取订单号
                    string total_fee = Request.Form["price"];           //获取总金额
                    string subject = Request.Form["subject"];           //商品名称、订单名称
                    string body = Request.Form["body"];                 //商品描述、订单备注、描述
                    string buyer_email = Request.Form["buyer_email"];   //买家支付宝账号
                    string trade_status = Request.Form["trade_status"]; //交易状态
                    Core.LogResult(total_fee);
                    string msg = "";
                    
                    PayType payType = PayType.WAIT_BUYER_PAY;
                    EOrderPay orderPay = new EOrderPay() { 
                        TradeNo=trade_no,
                        SaleId=order_no,
                        Price=Convert.ToDecimal(Convert.ToDouble(total_fee.Trim())),
                        Subject=subject,
                        Body=body,
                        BuyerEmail=buyer_email
                    };
                    
                    if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")
                    {//该判断表示买家已在支付宝交易管理中产生了交易记录，但没有付款

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        payType = PayType.WAIT_BUYER_PAY;
                        orderPay.TradeStatus = (int)payType;
                        _orderAccess.OrderPayProcess(orderPay);
                        msg="success1";  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "WAIT_SELLER_SEND_GOODS")
                    {//该判断示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        payType = PayType.WAIT_SELLER_SEND_GOODS;
                        orderPay.TradeStatus = (int)payType;
                        _orderAccess.OrderPayProcess(orderPay);
                        msg="success2";  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "WAIT_BUYER_CONFIRM_GOODS")
                    {//该判断表示卖家已经发了货，但买家还没有做确认收货的操作

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        payType = PayType.WAIT_BUYER_CONFIRM_GOODS;
                        orderPay.TradeStatus = (int)payType;
                        _orderAccess.OrderPayProcess(orderPay);
                        msg="success3";  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "TRADE_FINISHED")
                    {//该判断表示买家已经确认收货，这笔交易完成

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        payType = PayType.TRADE_FINISHED;
                        orderPay.TradeStatus = (int)payType;
                        _orderAccess.OrderPayProcess(orderPay);
                        msg="success4";  //请不要修改或删除
                    }
                    else
                    {
                        msg="1";  //其他状态判断。
                    }
                    //Core.LogResult(msg);

                    return Content(msg);
                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else//验证失败
                {
                    Core.LogResult("fail");
                    return Content("fail");
                }
            }
            else
            {
                Core.LogResult("无通知参数");
                return Content("无通知参数");
            }
        }

        public ActionResult AlipayReturn() 
        {
            SortedDictionary<string, string> sPara = GetRequestGet();
            EAlipayReturnData returnData = null;
            if (sPara.Count > 0)//判断是否有带返回参数
            {
                Notify aliNotify = new Notify();
                bool verifyResult = aliNotify.Verify(sPara, Request.QueryString["notify_id"], Request.QueryString["sign"]);
                
                if (verifyResult)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码

                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
                    string trade_no = Request.QueryString["trade_no"];              //支付宝交易号
                    string order_no = Request.QueryString["out_trade_no"];	        //获取订单号
                    string total_fee = Request.QueryString["price"];	            //获取总金额
                    string subject = Request.QueryString["subject"];                //商品名称、订单名称
                    string body = Request.QueryString["body"];                      //商品描述、订单备注、描述
                    string buyer_email = Request.QueryString["buyer_email"];        //买家支付宝账号
                    string receive_name = Request.QueryString["receive_name"];      //收货人姓名
                    string receive_address = Request.QueryString["receive_address"];//收货人地址
                    string receive_zip = Request.QueryString["receive_zip"];        //收货人邮编
                    string receive_phone = Request.QueryString["receive_phone"];    //收货人电话
                    string receive_mobile = Request.QueryString["receive_mobile"];  //收货人手机
                    string trade_status = Request.QueryString["trade_status"];      //交易状态

                    returnData = new EAlipayReturnData();
                    returnData.TradeNo = trade_no;
                    returnData.OutTradeNo = order_no;
                    returnData.Price = total_fee;
                    returnData.Subject = subject;
                    returnData.Body = body;
                    returnData.BuyerEmail = buyer_email;
                    returnData.ReceiveName = receive_name;
                    returnData.ReceiveAddress = receive_address;
                    returnData.ReceiveZip = receive_zip;
                    returnData.ReceivePhone = receive_phone;
                    returnData.ReceiveMobile = receive_mobile;
                    returnData.TradeStatus = trade_status;

                    if (Request.QueryString["trade_status"] == "WAIT_SELLER_SEND_GOODS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                    }
                }
            }
            return View(returnData);
        }

        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestPost()
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
            }

            return sArray;
        }

        /// <summary>
        /// 获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestGet()
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.QueryString[requestItem[i]]);
            }

            return sArray;
        }
    }
}
